package com.cx.common.core.constant;



import com.cx.common.core.dto.response.PageResp;
import com.cx.common.core.dto.response.Resp;
import org.springframework.http.HttpHeaders;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.text.MessageFormat;
import java.util.*;

/**
 * @author _
 * @date 2022/3/14
 */
public interface RespEnum {

    /**
     * 获取异常码
     *
     * @return
     */
    String getCode();

    /**
     * 获取异常信息
     *
     * @return
     */
    default String getMsg() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (Objects.isNull(attributes)) {
            return getEnglishMsg();
        }

        String language = attributes.getRequest().getHeader(HttpHeaders.ACCEPT_LANGUAGE);
        if (StringUtils.hasText(language)) {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.set(HttpHeaders.ACCEPT_LANGUAGE, language);
            List<Locale> locales = httpHeaders.getAcceptLanguageAsLocales();
            if (!CollectionUtils.isEmpty(locales)) {
                return getMsgByLanguage(locales.get(0).getLanguage());
            }
        }
        return getEnglishMsg();
    }

    /**
     * 获取繁体中文异常信息
     *
     * @return
     */
    String getTraditionalChineseMsg();

    /**
     * 获取英文异常信息
     *
     * @return
     */
    String getEnglishMsg();

    /**
     * 通过语言获取异常信息
     *
     * @param language
     * @return
     */
    default String getMsgByLanguage(String language) {
        if (StringUtils.isEmpty(language)) {
            return getEnglishMsg();
        }
        if ("zh".equalsIgnoreCase(language)
                || "zh-CN".equalsIgnoreCase(language)
                || language.startsWith("zh-Hans")) {
            return getMsg();
        }
        if ("zh-HK".equalsIgnoreCase(language)
                || "zh-TW".equalsIgnoreCase(language)
                || language.startsWith("zh-Hant")) {
            return getTraditionalChineseMsg();
        }
        return getEnglishMsg();
    }

    default <T> Resp<T> resp() {
        return resp(null);
    }

    default <T> Resp<T> resp(T data, Object... args) {
        return respByLanguage(null, data, args);
    }

    default <T> PageResp<T> pageResp() {
        return pageResp(Collections.emptyList(), false, 0, 0);
    }

    default <T> PageResp<T> pageResp(List<T> data, boolean hasNext, long totalPage, long totalCount, Object... args) {
        return pageRespByLanguage(null, data, hasNext, totalPage, totalCount, args);
    }

    default <T> PageResp<T> pageResp(PageResp<T> pageResp, Object... args) {
        return pageRespByLanguage(null, pageResp.getData(), pageResp.isHasNext(), pageResp.getTotalPage(), pageResp.getTotalCount(), args);
    }

    default <T> Resp<T> respByLanguage(String language) {
        return respByLanguage(language, null);
    }

    default <T> Resp<T> respByLanguage(String language, T data, Object... args) {
        String msg = StringUtils.isEmpty(language) ? getMsg() : getMsgByLanguage(language);
        return Resp.<T>builder().code(getCode()).msg(MessageFormat.format(msg, args)).data(data).build();
    }

    default <T> PageResp<T> pageRespByLanguage(String language) {
        return pageRespByLanguage(language, Collections.emptyList(), false, 0, 0);
    }

    default <T> PageResp<T> pageRespByLanguage(String language, List<T> data, boolean hasNext, long totalPage, long totalCount, Object... args) {
        String msg = StringUtils.isEmpty(language) ? getMsg() : getMsgByLanguage(language);
        return PageResp.<T>builder().code(getCode()).msg(MessageFormat.format(msg, args))
                .data(Optional.ofNullable(data).orElse(Collections.emptyList()))
                .hasNext(hasNext).totalPage(totalPage).totalCount(totalCount)
                .build();
    }
}
